package org.chen.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.chen.client.HeyGenClient;
import org.chen.common.exception.ServiceException;
import org.chen.domain.entity.ApiKeyEntity;
import org.chen.mapper.ApiKeyMapper;
import org.chen.service.ApiKeyService;
import org.chen.vo.QuotaVO;
import org.chen.vo.UserInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class ApiKeyServiceImpl extends ServiceImpl<ApiKeyMapper, ApiKeyEntity> implements ApiKeyService {
    @Autowired
    private HeyGenClient heyGenClient;

    @Autowired
    private ApiKeyMapper apiKeyMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String API_KEY_PREFIX = "apiKey:";

    // 增加清除缓存的方法
    private void clearApiKeyCache() {
        // 删除Redis中的API Key列表
        redisTemplate.delete("apiKeys");

        // 可以选择性地删除所有与API Key相关的配额缓存
        Set<String> keyPattern = redisTemplate.keys(API_KEY_PREFIX + "*");
        if (keyPattern != null && !keyPattern.isEmpty()) {
            redisTemplate.delete(keyPattern);
        }
    }

    @Override
    public QuotaVO getQuota(Long id) {
        ApiKeyEntity apiKey = this.getById(id);
        if (apiKey == null) {
            throw new ServiceException("API Key不存在");
        }

        QuotaVO quotaVO = heyGenClient.getQuota(apiKey.getApiKey());
        // 更新数据库中的配额
        if (quotaVO.getData() != null) {
            apiKey.setRemainingQuota(quotaVO.getData().getRemaining_quota());
            UserInfoVO userInfo = heyGenClient.getUserInfo(apiKey.getApiKey());
            apiKey.setEmail(userInfo.getData().getEmail());

            apiKeyMapper.updateById(apiKey);

            redisTemplate.opsForValue().set(
                    API_KEY_PREFIX + apiKey.getApiKey() + ":quota",
                    String.valueOf(apiKey.getRemainingQuota()),
                    1,
                    TimeUnit.DAYS
            );
        }else {
            apiKey.setErrorMessage(quotaVO.getError().getMessage());
        }

        return quotaVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveApiKey(ApiKeyEntity apiKey) {
        // 验证API key是否有效
        if (apiKey == null) {
            throw new ServiceException("API Key 不能为空");
        }

        boolean exists = apiKeyMapper.exists(new QueryWrapper<ApiKeyEntity>().eq("api_key", apiKey.getApiKey()));
        if (exists) {
            throw new ServiceException("此 API Key 已存在");
        }

        try {
            QuotaVO quotaVO = heyGenClient.getQuota(apiKey.getApiKey());
            // 获取并设置初始配额
            if (quotaVO.getData() != null) {
                apiKey.setRemainingQuota(quotaVO.getData().getRemaining_quota());
                UserInfoVO userInfo = heyGenClient.getUserInfo(apiKey.getApiKey());
                apiKey.setEmail(userInfo.getData().getEmail());
            }else {
                apiKey.setErrorMessage(quotaVO.getError().getMessage());
            }
            boolean result = save(apiKey);

            // 添加新的API Key后清除缓存，强制重新加载
            if (result) {
                clearApiKeyCache();
            }

            return result;
        } catch (Exception e) {
            throw new ServiceException("API Key验证失败");
        }
    }

    // 重写更新方法
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateById(ApiKeyEntity apiKey) {
        boolean result = super.updateById(apiKey);
        if (result) {
            clearApiKeyCache();
        }
        return result;
    }

    // 重写删除方法
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeById(Long id) {
        boolean result = super.removeById(id);
        if (result) {
            clearApiKeyCache();
        }
        return result;
    }

    // 重写批量删除方法
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByIds(List<Long> ids) {
        boolean result = super.removeByIds(ids);
        if (result) {
            clearApiKeyCache();
        }
        return result;
    }
}
